package com.qianji.petmall.product.service.impl;

import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qianji.common.constant.ProductConstant;
import com.qianji.common.to.SkuHasStockVo;
import com.qianji.common.to.SkuRoundTo;
import com.qianji.common.to.SupBoundTo;
import com.qianji.common.to.es.SkuEsModel;
import com.qianji.common.utils.PageUtils;
import com.qianji.common.utils.Query;
import com.qianji.common.utils.R;
import com.qianji.petmall.product.dao.SpuInfoDao;
import com.qianji.petmall.product.entity.*;
import com.qianji.petmall.product.feign.CouponFeignService;
import com.qianji.petmall.product.feign.SearchFeignService;
import com.qianji.petmall.product.feign.WareFeignService;
import com.qianji.petmall.product.service.*;
import com.qianji.petmall.product.vo.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;


@Service
public class SpuInfoServiceImpl extends ServiceImpl<SpuInfoDao, SpuInfoEntity> implements SpuInfoService {

    @Autowired
    private SpuInfoDescService spuInfoDescService;
    @Autowired
    private SpuImagesService spuImagesService;
    @Autowired
    private ProductAttrValueService productAttrValueService;
    @Autowired
    private AttrService attrService;
    @Autowired
    private SkuSaleAttrValueService skuSaleAttrValueService;
    @Autowired
    private SkuInfoService skuInfoService;
    @Autowired
    private SkuImagesService skuImagesService;
    @Autowired
    private CouponFeignService couponFeignService;
    @Autowired
    private BrandService brandService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private WareFeignService wareFeignService;
    @Autowired
    private SearchFeignService searchFeignService;
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                new QueryWrapper<SpuInfoEntity>()
        );

        return new PageUtils(page);
    }

    @Transactional
    @Override
    public void saveSpuInfo(SpuSaveVo saveVo) {
        /**
         * // pms_spu_info
         *     private String spuName;//商品名称   pms_spu_info
         *     private String spuDescription;//商品描述   pms_spu_info
         *     private Long catalogId;//所属分类id   pms_spu_info
         *     private Long brandId;//品牌id   pms_spu_info
         *     private BigDecimal weight;//页面传的重量   pms_spu_info
         *     private int publishStatus;//上架状态[0 - 下架，1 - 上架]   pms_spu_info
         *
         *     //pms_spu_info_desc
         *     private List<String> decript;//图片的商品介绍 存的图片路径
         *
         *     //页面传入的路径pms_spu_images
         *     private List<String> images;//图片存储的路径和默认显示
         *
         *     //页面传入的值
         *     private Bounds bounds;//会员的积分和成长值
         *
         *     //pms_product_attr_value
         *     private List<BaseAttrs> baseAttrs;//参数的id和信息
         */
        //1.保存页面的pms_spu_info基本信息 为了以后方法的复用，最好自己定义service
        SpuInfoEntity spuInfoEntity = new SpuInfoEntity();
        BeanUtils.copyProperties(saveVo,spuInfoEntity);
        spuInfoEntity.setCreateTime(new Date());
        spuInfoEntity.setUpdateTime(new Date());
        this.SaveSupInfo(spuInfoEntity);
        //2.decript 图片的商品介绍 存的图片路径 pms_spu_info_desc
        List<String> decript = saveVo.getDecript();
        SpuInfoDescEntity spuInfoDescEntity = new SpuInfoDescEntity();
        spuInfoDescEntity.setDecript(decript.toString());
        spuInfoDescEntity.setSpuId(spuInfoEntity.getId());
        spuInfoDescService.SaveSupDesc(spuInfoDescEntity);
        //3.images 图片存储的路径和默认显示  页面传入的路径pms_spu_images
        List<String> images = saveVo.getImages();
        spuImagesService.saveImages(spuInfoEntity.getId(),images);
        //4.baseAttrs 参数的id和信息 pms_product_attr_value
        List<BaseAttrs> baseAttrs = saveVo.getBaseAttrs();
        productAttrValueService.saveAttrValue(baseAttrs,spuInfoEntity.getId());
        //5.bounds 会员的积分和成长值 页面传入的值
        Bounds bounds = saveVo.getBounds();
        SupBoundTo supBoundTo = new SupBoundTo();
        BeanUtils.copyProperties(bounds,supBoundTo);
        supBoundTo.setSpuId(spuInfoEntity.getId());
        R r = couponFeignService.saveSupBounds(supBoundTo);
        if (r.getCode()!=0){
            log.error("远程保存spu积分信息失败");
        }
        /**
         *     //pms_sku_sale_attr_value
         *     private List<Attr> attr;//存的第三部分的内存版本信息
         *     //pms_sku_info
         *     private String skuName;//sku名称
         *     private BigDecimal price;//价格
         *     private String skuTitle;//标题
         *     private String skuSubtitle;//副标题
         *     //pms_sku_images
         *     private List<Images> images;
         *
         *     private List<String> descar;//对应的版本和颜色 ["8+256", "罗兰紫"]
         *
         *     //sms_sku_ladder  SMS
         *     private int fullCount;//满几件
         *     private BigDecimal discount;//打几折
         *
         *     private int countStatus;//
         *
         *     //sms_sku_full_reduction SMS
         *     private BigDecimal fullPrice;//满多少
         *     private BigDecimal reducePrice;//减多少
         *
         *     private int priceStatus;
         *     //sms_member_price
         *     private List<MemberPrice> memberPrice;
         */
        List<Skus> skus = saveVo.getSkus();
        skus.forEach(item->{
            String defauleImg = "";
            for (Images image:item.getImages()) {
                if (image.getDefaultImg()==1){
                    defauleImg = image.getImgUrl();
                }
            }
            /**
             * pms_sku_info
             *          *     private String skuName;//sku名称
             *          *     private BigDecimal price;//价格
             *          *     private String skuTitle;//标题
             *          *     private String skuSubtitle;//副标题
             */
            SkuInfoEntity skuInfoEntity = new SkuInfoEntity();
            BeanUtils.copyProperties(item,skuInfoEntity);
            skuInfoEntity.setSpuId(spuInfoEntity.getId());
            skuInfoEntity.setBrandId(spuInfoEntity.getBrandId());
            skuInfoEntity.setCatalogId(spuInfoEntity.getCatalogId());
            skuInfoEntity.setSaleCount(0L);
            skuInfoEntity.setSkuDefaultImg(defauleImg);
            skuInfoService.saveSkuInfo(skuInfoEntity);
            List<Images> itemImages = item.getImages();
            /**
             * // pms_sku_images
             * // private List<Images> images;
             */
            Long skuId = skuInfoEntity.getSkuId();
            List<SkuImagesEntity> collect = itemImages.stream().filter(entity->{
                //返回true就是需要，返回false就是不需要
                return StringUtils.isNotEmpty(entity.getImgUrl());
            }).map(img -> {
                SkuImagesEntity skuImagesEntity = new SkuImagesEntity();
                skuImagesEntity.setSkuId(skuId);
                skuImagesEntity.setImgUrl(img.getImgUrl());
                skuImagesEntity.setDefaultImg(img.getDefaultImg());
                return skuImagesEntity;
            }).collect(Collectors.toList());
            // TODO 没有照片路径的不显示
            skuImagesService.saveSkuImages(collect);

            /**
             *   //6.pms_sku_sale_attr_value
             *   //private List<Attr> attr;//存的第三部分的内存版本信息
             */
            List<Attr> attr = item.getAttr();
            List<SkuSaleAttrValueEntity> collects = attr.stream().map(attrs -> {
                SkuSaleAttrValueEntity skuSaleAttrValueEntity = new SkuSaleAttrValueEntity();
//                AttrEntity byId = attrService.getById(spuInfoEntity.getId());
//                skuSaleAttrValueEntity.setSkuId(skuId);
//                skuSaleAttrValueEntity.setAttrId(byId.getAttrId());
//                skuSaleAttrValueEntity.setAttrName(byId.getAttrName());
//                skuSaleAttrValueEntity.setAttrValue(byId.getValueSelect());
                BeanUtils.copyProperties(attrs,skuSaleAttrValueEntity);
                skuSaleAttrValueEntity.setSkuId(skuId);
                return skuSaleAttrValueEntity;
            }).collect(Collectors.toList());
            skuSaleAttrValueService.saveSaleAttrValue(collects);
            /**
             * //sms_sku_ladder  SMS
             *          *     private int fullCount;//满几件
             *          *     private BigDecimal discount;//打几折
             */
            SkuRoundTo skuRoundTo = new SkuRoundTo();
            BeanUtils.copyProperties(item,skuRoundTo);
            skuRoundTo.setSkuId(skuId);
            skuRoundTo.setMemberPrice(item.getMemberPrice());
            if(skuRoundTo.getFullCount()>0 || skuRoundTo.getFullPrice().doubleValue()>0){
                R r1 = couponFeignService.saveSkuLadder(skuRoundTo);
                if (r1.getCode()!=0){
                    log.error("远程保存sku积分信息失败");
                }
            }

        });
    }

    @Override
    public void SaveSupInfo(SpuInfoEntity spuInfoEntity) {
        this.baseMapper.insert(spuInfoEntity);
    }

    @Override
    public PageUtils queryPageByCondition(Map<String, Object> params) {
        QueryWrapper<SpuInfoEntity> spuInfoEntityQueryWrapper = new QueryWrapper<>();
        String key = (String) params.get("key");
        if (StringUtils.isNotEmpty(key)){
            spuInfoEntityQueryWrapper.and(w->{
                w.eq("id",key).or().like("spu_name",key);
            });
        }
        String catelogId = (String) params.get("catelogId");
        if (StringUtils.isNotEmpty(catelogId) && !"0".equals(catelogId)){
            spuInfoEntityQueryWrapper.eq("catalog_id",catelogId);
        }
        String brandId = (String) params.get("brandId");
        if (StringUtils.isNotEmpty(brandId) && !"0".equals(brandId)){
            spuInfoEntityQueryWrapper.eq("brand_id",brandId);
        }
        String status = (String) params.get("status");
        if (StringUtils.isNotEmpty(status)){
            spuInfoEntityQueryWrapper.eq("publish_status",status);
        }
        IPage<SpuInfoEntity> page = this.page(new Query<SpuInfoEntity>().getPage(params), spuInfoEntityQueryWrapper);
        return new PageUtils(page);
    }

    @Override
    public SpuInfoEntity getSkuInfoBySpuId(Long skuId) {
        SkuInfoEntity byId = skuInfoService.getById(skuId);
        Long spuId = byId.getSpuId();
        SpuInfoEntity spuInfoEntity = this.baseMapper.selectById(spuId);
        return spuInfoEntity;

    }

    @Override
    public void getSkuInfoBySkuId(Long spuId) {
        //获取当前spuId对应的sku的所有信息
        List<SkuInfoEntity> skuBySpuId = skuInfoService.getSkuBySpuId(spuId);

        //TODO 4、根据spu查出当前sku的所有可以被用来检索的规格属性
        List<ProductAttrValueEntity> attrValueEntities = productAttrValueService.list(new QueryWrapper<ProductAttrValueEntity>().eq("spu_id", spuId));
        // 2.2 stream 流：从 attrValues 中提取出 attrId ，转成集合 attrIds
        List<Long> collect = attrValueEntities.stream().map(ProductAttrValueEntity::getAttrId).collect(Collectors.toList());
        //TODO 通过遍历的attrId得到所有的attr参数
        List<Long> list = attrService.selectSearchAttrIds(collect);
        // 2.4 将 list 转成 Set<Long> attrIdSet
        Set<Long> hashSet = new HashSet<>(list);
        // 2.5 stream 流：attrValueEntities
        List<SkuEsModel.Attr> attrList = attrValueEntities.stream().filter(entity ->{
            return hashSet.contains(entity.getAttrId());
        }).map(entity -> {
            SkuEsModel.Attr attr = new SkuEsModel.Attr();
            BeanUtils.copyProperties(entity, attr);
            return attr;
        }).collect(Collectors.toList());

        // TODO 发动远程调用，查看是否有库存
        Map<Long, Boolean> map = null;
        //获取所有skuId
        List<Long> skuIds = skuBySpuId.stream().map(SkuInfoEntity::getSkuId).collect(Collectors.toList());
        try {
            R r = wareFeignService.skuStock(skuIds);
            map = r.getData(new TypeReference<List<SkuHasStockVo>>(){
            }).stream().collect(Collectors.toMap(SkuHasStockVo::getSkuId, SkuHasStockVo::getHasStock));
        }catch (Exception e){
            log.error("远程调用服务失败",e);
        }

        Map<Long, Boolean> finalMap = map;
        List<SkuEsModel> skuEsModels = skuBySpuId.stream().map(item -> {
            SkuEsModel skuEsModel = new SkuEsModel();
            BeanUtils.copyProperties(item, skuEsModel);
            // 另外需要set的属性
            //skuPrice,skuImg
            skuEsModel.setSkuPrice(item.getPrice());
            skuEsModel.setSkuImg(item.getSkuDefaultImg());
            //TODO 2、热度评分 hotScore
            skuEsModel.setHotScore(0L);
            //添加品牌的其它属性
            //TODO brandName,brandImg
            BrandEntity brand = brandService.getById(item.getBrandId());
            skuEsModel.setBrandName(brand.getName());
            skuEsModel.setBrandImg(brand.getLogo());
            //TODO catalogName
            CategoryEntity category = categoryService.getById(item.getCatalogId());
            skuEsModel.setCatalogName(category.getName());
            //TODO attrs
            skuEsModel.setAttrs(attrList);
            //TODO hasStock设置是否有库存
            if (finalMap == null) {
                skuEsModel.setHasStock(false);
            } else {
                skuEsModel.setHasStock(finalMap.get(item.getSkuId()));
            }
            return skuEsModel;
        }).collect(Collectors.toList());

        // TODO 5、将数据发给es进行保存：gulimall-search
        R r = searchFeignService.saveProduct(skuEsModels);
        if (r.getCode()==0){
            baseMapper.upSupStatus(spuId, ProductConstant.StatusEnum.UP_SPU.getCode());
        }else {
            log.error("远程调用失败");
        }
    }

}